package com.lzy.cloud.search.client.service.impl;

import com.lzy.cloud.search.client.entity.EsQuery;
import com.lzy.cloud.search.client.service.TermLevelQueriesService;
import com.lzy.cloud.search.client.util.EsClient;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import static org.elasticsearch.index.query.QueryBuilders.*;

/**
 * 术语查询
 * 通常用于结构化数据，如数字、日期和枚举，而不是全文字段
 */
@Service
public class TermLevelQueriesServiceImpl implements TermLevelQueriesService {

    @Autowired
    private EsClient client;

    @Override
    public SearchResponse termQuerys(EsQuery esQuery)   {
        QueryBuilder qb = termQuery(
                esQuery.getFieldName(),    //field
                esQuery.getFieldText()   //text
        );

        SearchResponse response = client.getConnection().prepareSearch(esQuery.getIndices())//可以是多个index
                .setTypes(esQuery.getTypes())//可以是多个类型
                .setQuery(qb)    // Query 查询条件
                .get();

        return response;
    }

    @Override
    public SearchResponse termsQuerys(EsQuery esQuery)   {
        QueryBuilder qb = termsQuery(
                esQuery.getFieldName(),    //field
                esQuery.getFieldNames());                    //values

        SearchResponse response = client.getConnection().prepareSearch(esQuery.getIndices())//可以是多个index
                .setTypes(esQuery.getTypes())//可以是多个类型
                .setQuery(qb)    // Query 查询条件
                .get();

        return response;
    }

    @Override
    public SearchResponse rangeQuerys(EsQuery esQuery)   {

//        gte() :范围查询将匹配字段值大于或等于此参数值的文档。
//        gt() :范围查询将匹配字段值大于此参数值的文档。
//        lte() :范围查询将匹配字段值小于或等于此参数值的文档。
//        lt() :范围查询将匹配字段值小于此参数值的文档。
//        from() 开始值 to() 结束值 这两个函数与includeLower()和includeUpper()函数配套使用。
//        includeLower(true) 表示 from() 查询将匹配字段值大于或等于此参数值的文档。
//        includeLower(false) 表示 from() 查询将匹配字段值大于此参数值的文档。
//        includeUpper(true) 表示 to() 查询将匹配字段值小于或等于此参数值的文档。
//        includeUpper(false) 表示 to() 查询将匹配字段值小于此参数值的文档。

//        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("age");
//        rangeQueryBuilder.from(19);
//        rangeQueryBuilder.to(21);
//        rangeQueryBuilder.includeLower(true);
//        rangeQueryBuilder.includeUpper(true);

        //上面代码等价于下面代码

        QueryBuilder qb = QueryBuilders.rangeQuery(esQuery.getFieldName()).gte(esQuery.getGte()).lte(esQuery.getLte());


        SearchResponse response = client.getConnection().prepareSearch(esQuery.getIndices())//可以是多个index
                .setTypes(esQuery.getTypes())//可以是多个类型
                .setQuery(qb)    // Query 查询条件
                .get();

        return response;
    }

    @Override
    public SearchResponse existsQuerys(EsQuery esQuery)   {
        QueryBuilder qb = existsQuery(esQuery.getFieldName());

        SearchResponse response = client.getConnection().prepareSearch(esQuery.getIndices())//可以是多个index
                .setTypes(esQuery.getTypes())//可以是多个类型
                .setQuery(qb)    // Query 查询条件
                .get();

        return response;
    }

    /**
     * 查找指定字段包含以指定的精确前缀开头的值的文档。
     *
     * @ 
     */
    @Override
    public SearchResponse prefixQuerys(EsQuery esQuery)   {
        QueryBuilder qb = prefixQuery(
                esQuery.getFieldName(),    //field
                esQuery.getPrefix()     //prefix
        );

        SearchResponse response = client.getConnection().prepareSearch(esQuery.getIndices())//可以是多个index
                .setTypes(esQuery.getTypes())//可以是多个类型
                .setQuery(qb)    // Query 查询条件
                .get();

        return response;
    }

    /**
     * 通配符查询
     *
     * @ 
     */
    @Override
    public SearchResponse wildcardQuerys(EsQuery esQuery)   {
        QueryBuilder qb = wildcardQuery(
                esQuery.getFieldName(),
                esQuery.getWildcard()
        );

        SearchResponse response = client.getConnection().prepareSearch(esQuery.getIndices())//可以是多个index
                .setTypes(esQuery.getTypes())//可以是多个类型
                .setQuery(qb)    // Query 查询条件
                .get();

        return response;
    }

    /**
     * 正则表达式查询
     *
     * @ 
     */
    @Override
    public SearchResponse regexpQuerys(EsQuery esQuery)   {

        QueryBuilder qb = regexpQuery(
                esQuery.getFieldName(),        //field
                esQuery.getRegexp());             //regexp
        SearchResponse response = client.getConnection().prepareSearch(esQuery.getIndices())//可以是多个index
                .setTypes(esQuery.getTypes())//可以是多个类型
                .setQuery(qb)    // Query 查询条件
                .get();

        return response;
    }

    /**
     * 模糊查找
     *
     * @return
     * @ 
     */
    @Override
    public SearchResponse fuzzyQuerys(EsQuery esQuery)   {

        QueryBuilder qb = fuzzyQuery(
                esQuery.getFieldName(),     //field
                esQuery.getFieldText()    //text
        ).fuzziness(Fuzziness.TWO);

        SearchResponse response = client.getConnection().prepareSearch(esQuery.getIndices())//可以是多个index
                .setTypes(esQuery.getTypes())//可以是多个类型
                .setQuery(qb)    // Query 查询条件
                .get();

        return response;
    }


}
